//// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
//package com.linqingying.gitcode.pullrequest.ui.toolwindow.model
//
//import com.intellij.collaboration.async.combineState
//import com.intellij.collaboration.async.launchNow
//import com.intellij.collaboration.async.mapScoped
//import com.intellij.collaboration.async.mapState
//import com.intellij.collaboration.ui.toolwindow.ReviewToolwindowViewModel
//import com.intellij.collaboration.util.URIUtil
//import com.intellij.openapi.components.Service
//import com.intellij.openapi.components.service
//import com.intellij.openapi.project.Project
//import com.intellij.platform.util.coroutines.childScope
//import kotlinx.coroutines.CoroutineScope
//import kotlinx.coroutines.Dispatchers
//import kotlinx.coroutines.flow.*
//import kotlinx.coroutines.launch
//import kotlinx.coroutines.withContext
//import org.jetbrains.annotations.ApiStatus
//import com.linqingying.gitcode.authentication.accounts.GCAccountManager
//import com.linqingying.gitcode.authentication.accounts.GitCodeAccount
//import com.linqingying.gitcode.pullrequest.GCRepositoryConnectionManager
//import com.linqingying.gitcode.pullrequest.config.GitCodePullRequestsProjectUISettings
//import com.linqingying.gitcode.pullrequest.ui.selector.GCRepositoryAndAccountSelectorViewModel
//import com.linqingying.gitcode.util.GCGitRepositoryMapping
//import com.linqingying.gitcode.util.GCHostedRepositoriesManager
//
//@ApiStatus.Experimental
//@Service(Service.Level.PROJECT)
//class GCPRToolWindowViewModel internal constructor(private val project: Project, parentCs: CoroutineScope)
//  : ReviewToolwindowViewModel<GCPRToolWindowProjectViewModel> {
//
//  private val accountManager: GCAccountManager get() = service()
//  private val repositoriesManager: GCHostedRepositoriesManager get() = project.service()
//  private val connectionManager: GCRepositoryConnectionManager get() = project.service()
//  private val settings: GitCodePullRequestsProjectUISettings
//    get() = GitCodePullRequestsProjectUISettings.getInstance(project)
//
//  //TODO: switch to Default dispatcher
//  private val cs = parentCs.childScope(Dispatchers.Main)
//
//  val isAvailable: StateFlow<Boolean> = repositoriesManager.knownRepositoriesState.mapState(cs) {
//    it.isNotEmpty()
//  }
//
//  private val _activationRequests = MutableSharedFlow<Unit>(1)
//  internal val activationRequests: Flow<Unit> = _activationRequests.asSharedFlow()
//
//  private val singleRepoAndAccountState: StateFlow<Pair<GCGitRepositoryMapping, GitCodeAccount>?> =
//    combineState(cs, repositoriesManager.knownRepositoriesState, accountManager.accountsState) { repos, accounts ->
//      repos.singleOrNull()?.let { repo ->
//        accounts.singleOrNull { URIUtil.equalWithoutSchema(it.server.toURI(), repo.repository.serverPath.toURI()) }?.let {
//          repo to it
//        }
//      }
//    }
//
//  val selectorVm: GCRepositoryAndAccountSelectorViewModel by lazy {
//    val vm = GCRepositoryAndAccountSelectorViewModel(cs, repositoriesManager, accountManager, ::connect)
//    cs.launchNow {
//      repositoriesManager.knownRepositoriesState.collectLatest { repos ->
//        if (connectionManager.connectionState.value != null) {
//          return@collectLatest
//        }
//        val (url, account) = settings.selectedUrlAndAccount ?: return@collectLatest
//        val repo = repos.find {
//          it.remote.url == url
//        } ?: return@collectLatest
//        with(vm) {
//          repoSelectionState.value = repo
//          accountSelectionState.value = account
//          submitSelection()
//        }
//      }
//    }
//
//    //TODO: only do when UI is showing
//    cs.launchNow {
//      singleRepoAndAccountState.collect {
//        if (it != null) {
//          with(vm) {
//            repoSelectionState.value = it.first
//            accountSelectionState.value = it.second
//            submitSelection()
//          }
//        }
//      }
//    }
//    vm
//  }
//
//  private suspend fun connect(repo: GCGitRepositoryMapping, account: GitCodeAccount) {
//    withContext(cs.coroutineContext) {
//      connectionManager.openConnection(repo, account)
//      settings.selectedUrlAndAccount = repo.remote.url to account
//    }
//  }
//
//  override val projectVm: StateFlow<GCPRToolWindowProjectViewModel?> by lazy {
//    project.service<GCRepositoryConnectionManager>().connectionState
//      .mapScoped { ctx -> ctx?.let { GCPRToolWindowProjectViewModel(project, this, this@GCPRToolWindowViewModel, it) } }
//      .stateIn(cs, SharingStarted.Lazily, null)
//  }
//
//  fun canResetRemoteOrAccount(): Boolean = connectionManager.connectionState.value != null && singleRepoAndAccountState.value == null
//
//  fun resetRemoteAndAccount() {
//    cs.launch {
//      settings.selectedUrlAndAccount = null
//      connectionManager.closeConnection()
//    }
//  }
//
//  fun activate() {
//    _activationRequests.tryEmit(Unit)
//  }
//
//  fun activateAndAwaitProject(action: GCPRToolWindowProjectViewModel.() -> Unit) {
//    cs.launch {
//      _activationRequests.emit(Unit)
//      projectVm.filterNotNull().first().action()
//    }
//  }
//
//  fun loginIfPossible() {
//    // init selector, so that auto-login is done automatically
//    selectorVm
//  }
//}
